/*
 * Framework for communicating between the MySpace OpenSocial API and 
 * Adobe Flash via ExternalInterface.
 *
 * @author SplashCast (www.splashcastmedia.com)
 * @author Brock Henderson
 * @version 1.48
 *
 * Distributed under the MIT License
 *
*/

var swf_ref;
var debug_ref;
var debugging_on;
var framework_ver = "1.48";

/* Debugging trace function that will print out to a DIV with the ID 'debug_output'
 * @param msg [string] - message to be printed
 * @param o [object] - [optional] one-dimensional object tree whos key/value pairs will be printed
*/
function debugOut(msg, o) {
	if (!debugging_on) return;
	try {
		debug_ref.innerHTML += msg+"<br>";
		if (o != null) {
			for (var x in o) {
				debug_ref.innerHTML += " obj."+x+" : "+o[x]+"<br>";
			}
		}
	}
	catch (e) {}
}

/* Gets an object reference for a OBJECT/EMBED combo Flash SWF
 * @param name [string] - ID/NAME of the OBJECT/EMBED
 * @returns reference to the SWF object
*/
function getSWF(name) {
	var isIE = window.navigator.appName.indexOf("Microsoft") != -1;
 	return (isIE) ? window[name] : document[name];
}

/* Writes the SWF OBJECT/EMBED into the innerHTML of the target_id element
 * @param url [string] - web address of the SWF file
 * @param w [string] - width value to be written into the elements
 * @param h [string] - height value to be written into the elements
 * @param target_id [string] - ID of the element to write the HTML into
 * @returns - string value of embed if target_id is null or boolean value 'true' if the function successfully executes
*/
function writeEmbed(url,w,h,swf_id,target_id) {
	// setup debugging
	try {
		debug_ref = document.getElementById("debug_output");
		debugging_on = true;
	}
	catch (e) {
		debugging_on = false;
	}
        debugOut("myspace-opensocial-flash.js version: "+framework_ver+"<br />writeEmbed()");
	// build embed str
	var fvar_str = "";
	try {
		if (fvars) {
			for (var x in fvars) fvar_str += x+"="+fvars[x]+"&";
			fvar_str = fvar_str.substr(0,fvar_str.length-1);
			debugOut("FlashVars constructed:\n["+fvar_str+"]");
		}
	}
	catch (e) {
		fvars = false;
	}
	var embed_str = "<object classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\"";
	embed_str += "codebase=\"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0\"";
	embed_str += " width=\""+w+"\"";
	embed_str += " height=\""+h+"\"";
	embed_str += " id=\""+swf_id+"\">";
	embed_str += "<param name=\"allowScriptAccess\" value=\"always\" />";
	embed_str += "<param name=\"allowNetworking\" value=\"all\" />";
	embed_str += "<param name=\"wmode\" value=\"opaque\" />";
	embed_str += "<param name=\"movie\" value=\""+url+"\" />";
	if (fvars) embed_str += "<param name=\"flashvars\" value=\""+fvar_str+"\" />";
	embed_str += "<embed type=\"application/x-shockwave-flash\"";
	embed_str += " allowScriptAccess=\"always\"";
	embed_str += " allowNetworking=\"all\"";
	embed_str += " wmode=\"opaque\"";
	embed_str += " src=\""+url+"\"";
	embed_str += " width=\""+w+"\"";
	embed_str += " height=\""+h+"\"";
	if (fvars) embed_str += " flashvars=\""+fvar_str+"\"";
	embed_str += " name=\""+swf_id+"\">";
	embed_str += "</embed></object>";
	// write embed to target element or return as string
	if (target_id != null) {
		document.getElementById(target_id).innerHTML = embed_str;
		swf_ref = getSWF(swf_id);
		if (debug_ref != null) debugOut("SWF refrerence aquired");
		return true;
	}
	else return embed_str;
}

/* SWF OpenSocial connection activated
 * @param msg - A message from the SWF
 * @returns boolean - True value to confirm method was successful
*/
function swfOsActivate(msg) {
	debugOut(msg);
	return true;
}

/* Gets Browser Info
 * @returns string Browser name & version
*/
function getBrowserVersion() {
	return navigator.appName+" "+navigator.appVersion; //userAgent
}

/* Sets user specific key/value data for app
 * @param data [object] - object to be parsed into individual key/value update calls
 * @param target [string] - user reference to associate with data (currently only 'OWNER' is supported)
 * @returns boolean value 'true' if the function successfully executes
*/
function setUserAppData(data, target) {
	debugOut("Setting user app data:");
	if (target == null) target = "viewer";
	var dataRequest = opensocial.newDataRequest();
	for (var x in data) {
		debugOut("set ["+x+"] to ["+data[x]+"]");
		dataRequest.add(dataRequest.newUpdatePersonAppDataRequest(target, x, data[x]),"appdata");
	}	
	dataRequest.send(resultSetUserAppData);
	return true;
}

/* Callback for setUserAppData()
 * @param data [opensocial.DataResponse] - results for the call
*/
function resultSetUserAppData(data) {
	var appData = data.get("appdata");
	debugOut("set user data result:");
	if (appData.hadError()) {
		debugOut(" There was an error setting user data");
		debugOut(" ERROR Code: "+appData.getErrorCode());
		debugOut(" Message: "+appData.getErrorMessage());
	}
	else debugOut(" The user data was successfully set");
	var resultData = appData.getData();
	try {
		swf_ref.externalMethodCallback("setUserAppData", resultData);
	}
	catch(e) {
		debugOut("Error calling SWF method externalMethodCallback()", e);
	}
}

/* Gets user specific key/value data for app
 * @param target [string] - user reference to return data for
 * @param keys [array or string] - [optional] array of specific keys to be returned or string '*' to indicate all
 * @returns boolean value 'true' if the function successfully executes
*/
function getUserAppData(target, keys) {
	debugOut("Setting user app data:");
	if (target == null) target = "viewer";
	if (keys == null || keys.length == 0) keys = "*";
	debugOut("User ["+target+"] Keys ["+keys+"]");
	var dataRequest = opensocial.newDataRequest();
	dataRequest.add(dataRequest.newFetchPersonAppDataRequest(target, keys),"appdata");	
	dataRequest.send(resultGetUserAppData);
	return true;
}

/* Callback for getUserAppData()
 * @param data [opensocial.DataResponse] - results for the call
*/
function resultGetUserAppData(data) {
	var appData = data.get("appdata");
	debugOut("get user data result:");
	if (appData.hadError()) {
		debugOut(" There was an error getting user data");
		debugOut(" ERROR Code: "+appData.getErrorCode());
		debugOut(" Message: "+appData.getErrorMessage());
	}
	else debugOut(" The user data was successfully got");
	var resultData = appData.getData();
	try {
		swf_ref.externalMethodCallback("getUserAppData", resultData);
	}
	catch(e) {
		debugOut("Error calling SWF method externalMethodCallback()", e);
	}
}

/* @returns [String] - path to the 64x64 pixel App Icon */
function getAppLargeIcon() {
	return myOpenSocialAppOpts[MyOpenSpace.Application.Field.ICON_LARGE];
}

/* @returns [String] - path to the 16x16 pixel App Icon */
function getAppSmallIcon() {
	return myOpenSocialAppOpts[MyOpenSpace.Application.Field.ICON_SMALL];
}

/* Interface for MySpace Messaging API 
 * @msg_title [String] - Title for message when applicable
 * @msg_body [String] - The message
 * @msg_type [String] - Type of message being sent
 * @ids [String | Array] - ID or IDs of users to message (at this time MS only supports messaging individual users)
*/
function sendMessage(msg_title, msg_body, type, ids) {
	//var msg = opensocial.newMessage(msg_body, {type:msg_type,title:msg_title});
    	var msg_type = opensocial.Message.Type[type];
    	if (msg_type == null) msg_type = type;
	debugOut("message type ["+msg_type+"] title ["+msg_title+"] created");
	var msg = opensocial.newMessage(msg_body);
	if (msg_title != null) msg.setField(opensocial.Message.Field.TITLE, msg_title);
	if (msg_type != null) msg.setField(opensocial.Message.Field.TYPE, msg_type);
	else msg.setField(opensocial.Message.Field.TYPE, "SEND_MESSAGE");
	//var token = MyOpenSpace.MySpaceContainer.OSToken;
	if (msg_type == "SHARE_APP") {
		debugOut("Use requestShareApp()");
		opensocial.Container.get().requestShareApp(ids, msg, resultSendMessage);
	}
	else {
		opensocial.Container.get().requestSendMessage(ids, msg, resultSendMessage);
	}
	//opensocial.Container.get().postTo(token, msg, ids);	
	debugOut("message sent");
	//swf_ref.relayMessage("opensocial.requestSendMessage() message sent");
	return true;
}

/* Callback for sendMessage() 
 * @param data [opensocial.DataResponse] - OpenSocial response object
*/
function resultSendMessage(data) {
	debugOut("message result:");
	if (data.hadError()) {
		debugOut(" There was an error sending the message");
		debugOut(" ERROR Code: "+data.getErrorCode());
		debugOut(" Message: "+data.getErrorMessage());
	}
	else debugOut(" The message was successfully sent");
	try {
		swf_ref.externalMethodCallback("sendMessage", data);
	}
	catch(e) {
		debugOut("Error calling SWF method externalMethodCallback()", e);
	}
}

/* Pubilsh User Activity
 * @temp_id [String] - ID for the template to use
 * @url [String] - Media URL
 * @priority [String] - ( HIGH | LOW ) priority of the activity call
*/
function createTemplateActivity(temp_id, url, priority, swf_params) {
	if (priority) priority = opensocial.CreateActivityPriority[priority];
	else priority = opensocial.CreateActivityPriority.HIGH;
	debugOut("Testing activities template ["+temp_id+"]<br />Params:");
	for (var x in swf_params) {
		debugOut("swf_params."+x+" ["+swf_params[x]+"]");
	}
	var params = {};
	params[opensocial.Activity.Field.TITLE_ID] = temp_id;
	params[opensocial.Activity.Field.TEMPLATE_PARAMS] = swf_params;
	debugOut("Check for media...");
	var mediaItemArray = [];
	if (url) {
		mediaItemArray.push(opensocial.newMediaItem("", url));
		debugOut("media URL: "+url);
	}
	else debugOut("no media url");
	params[opensocial.Activity.Field.MEDIA_ITEMS] = mediaItemArray;
	debugOut("Creating activity object...");
	var activity = opensocial.newActivity(params);
	debugOut("Make request with priority ["+priority+"]");
	opensocial.requestCreateActivity(activity, priority, resultCreateActivity);
	debugOut("Activity request has been made");
	return true;
}

/* Callback for createTemplateActivity() 
 * @param data [opensocial.DataResponse] - OpenSocial response object
*/
function resultCreateActivity(data) {
	debugOut("activity result:");
	if (data.hadError()) {
		debugOut(" There was an error sending the message");
		debugOut(" ERROR Code: "+data.getErrorCode());
		debugOut(" Message: "+data.getErrorMessage());
	}
	else {
		if (data.data_ == "1") debugOut(" The activity was approved by user");
		else if (data.data_ == "0") debugOut(" The activity was rejected by user");
		else debugOut(" The activity result is unknown ["+data.data_+"]");
	}
	try {
		swf_ref.externalMethodCallback("createActivity", data);
	}
	catch(e) {
		debugOut("Error calling SWF method externalMethodCallback()", e);
	}
}

/* Sends a Notification to a user
 * @param uid - User id to send notification to
 * @param note - notification text
*/
function createNotification(uid, note, button_name, button_params) {
	debugOut("Create notification for user ["+uid+"]");
	debugOut("Button ["+button_name+"] params:");
	for (var x in button_params) {
		debugOut(" "+x+" : "+button_params[x]);
	}
	debugOut("Notification Button URL Types:");
	for (x in MyOpenSpace.NotificationButton.UrlTypes) {
		debugOut(" type."+x+" ["+MyOpenSpace.NotificationButton.UrlTypes[x]+"]");
	}
	var button = MyOpenSpace.newNotificationButton(MyOpenSpace.NotificationButton.UrlTypes.CANVAS, button_name, button_params);
	debugOut("New button ["+button_name+"] deep_link ["+button_params.deep_link+"]");
	var buttons = [button];
	var params = {};
	params[MyOpenSpace.Notification.Field.BODY] = note;
	params[MyOpenSpace.Notification.Field.BUTTONS] = buttons;
	debugOut("Set param ["+params[MyOpenSpace.Notification.Field.BODY]+"]");
	var notification = MyOpenSpace.newNotification(params);
	debugOut("New Notification created");
	MyOpenSpace.requestCreateNotification(uid, notification, resultCreateNotification);
	debugOut("requestCreateNotification() called");
	return true;
}

/* Callback for createNotification() 
 * @param data [opensocial.DataResponse] - OpenSocial response object
*/
function resultCreateNotification(data) {
	debugOut("Notification result:");
	if (data.hadError()) {
		debugOut(" There was an error sending the message");
		debugOut(" ERROR Code: "+data.getErrorCode());
		debugOut(" Message: "+data.getErrorMessage());
	}
	else {
		debugOut("Notification data:",data);
	}
	try {
		swf_ref.externalMethodCallback("createNotification", data);
	}
	catch(e) {
		debugOut("Error calling SWF method externalMethodCallback()", e);
	}
}

/* Navigate to a different social network surface with parameters 
 * @param surface [String] - (canvas | home | profile) Social network surface to navigate to
 * @param params [Object] - Collection of key/value pairs to pass to the target surface
*/
function navigateTo(surface, params, ownerId) {
	var canvas_view = new gadgets.views.View(surface);
	gadgets.views.requestNavigateTo(canvas_view, params, ownerId);
}

/* Get OS parameters, including those set using navigateTo() 
 * @returns [Object] - key/value pairs of OS parameters
*/
function getParams() {
	//return opensocial.getEnvironment().getParams();
	// OS 0.8 
	return gadgets.views.getParams();
}